package com.hongkuncheng.cms.controller.admin;

import java.util.List;
import java.util.ArrayList;

import com.hongkuncheng.cms.helper.SecurityHelper;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.sql.JoinType;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Controller;
import com.hongkuncheng.cms.controller.BaseController;
import com.hongkuncheng.cms.helper.DataHelper;
import com.hongkuncheng.cms.helper.PageHelper;
import com.hongkuncheng.cms.helper.StringHelper;
import com.hongkuncheng.cms.model.Admin;
import com.hongkuncheng.cms.model.AdminGlobalpermission;
import com.hongkuncheng.cms.model.AdminReAdminRole;
import com.hongkuncheng.cms.model.AdminRole;
import com.hongkuncheng.cms.model.Zhuanti;
import com.hongkuncheng.cms.model.Columns;
import com.hongkuncheng.cms.model.Department;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 用户管理
 *
 * @author 洪坤成
 */
@Controller
@Transactional
@RequestMapping("admin/admin")
public class AadminController extends BaseController {

    // 用户列表
    @RequestMapping
    public String index() {
        Criteria criterAdmin = factorySession.createCriteria(Admin.class, "this_")
                .createAlias("adminReAdminRoles", "arac", JoinType.LEFT_OUTER_JOIN)
                .createAlias("arac.adminRole", "admin_adminrole", JoinType.LEFT_OUTER_JOIN);
        StringBuilder callbackparams = new StringBuilder();
        int departmentId = request.getParameter("departmentid") == null ? 0 :
                Integer.parseInt(request.getParameter("departmentid"));
        if (departmentId > 0) {
            criterAdmin.add(Restrictions.eq("department.id", departmentId));
            callbackparams.append("&departmentid=" + departmentId);
        }
        request.setAttribute("departmentid", departmentId);
        int adminroleId = request.getParameter("adminroleid") == null ? 0 :
                Integer.parseInt(request.getParameter("adminroleid"));
        if (adminroleId > 0) {
            criterAdmin.add(Restrictions.eq("admin_adminrole.id", adminroleId));
            callbackparams.append("&adminroleid=" + adminroleId);
        }
        request.setAttribute("adminroleid", adminroleId);
        int adminglobalpermissionId = request.getParameter("adminglobalpermissionid") == null ? 0 :
                Integer.parseInt(request.getParameter("adminglobalpermissionid"));
        if (adminglobalpermissionId > 0) {
            criterAdmin.add(Restrictions.eq("adminGlobalpermission.id", adminglobalpermissionId));
            callbackparams.append("&adminglobalpermissionid=" + adminglobalpermissionId);
        }
        request.setAttribute("adminglobalpermissionid", adminglobalpermissionId);
        String search = request.getParameter("search") == null ? "" : request.getParameter("search");
        if (!search.isEmpty()) {
            criterAdmin.add(Restrictions.disjunction()
                    .add(Restrictions.like("account", search, MatchMode.ANYWHERE))
                    .add(Restrictions.like("name", search, MatchMode.ANYWHERE))
                    .add(Restrictions.like("position", search, MatchMode.ANYWHERE))
                    .add(Restrictions.like("mobile", search, MatchMode.ANYWHERE))
                    .add(Restrictions.like("email", search, MatchMode.ANYWHERE))
                    .add(Restrictions.like("weixinId", search, MatchMode.ANYWHERE)));
            callbackparams.append("&search=" + search);
        }
        request.setAttribute("search", search);
        if (callbackparams.length() > 0) callbackparams.deleteCharAt(0);
        request.setAttribute("callbackparams", callbackparams);
        int pageIndex = request.getParameter("pageindex") == null || request.getParameter("callbackparams") != null &&
                !callbackparams.toString().equals(request.getParameter("callbackparams")) ? 1 :
                Integer.parseInt(request.getParameter("pageindex"));
        int datasize = getDataSize();
        List<Integer> adminIds = criterAdmin.setProjection(Projections.property("id"))
                .addOrder(Order.asc("sort")).setFirstResult((pageIndex - 1) * datasize).setMaxResults(datasize)
                .list();
        List<Admin> admins = new ArrayList<Admin>();
        if (adminIds.size() > 0) {
            admins = factorySession.createCriteria(Admin.class).add(Restrictions.in("id", adminIds))
                    .list();
            for (Admin admin : admins)
                if (admin.getFace() == null || admin.getFace().isEmpty())
                    admin.setFace("/image/admin/main/defaultface.jpg");
        }
        request.setAttribute("admins", admins);
        request.setAttribute("pageindex", pageIndex);
        int recordcount = admins.size() == 0 ? 0 :
                Integer.parseInt(criterAdmin.setProjection(Projections.countDistinct("id"))
                        .setFirstResult(0).uniqueResult().toString());
        request.setAttribute("recordcount", recordcount);
        int pagecount = DataHelper.calcPageCount(recordcount, datasize);
        request.setAttribute("pagecount", pagecount);
        List<Department> departments = factorySession.createCriteria(Department.class)
                .addOrder(Order.asc("sort")).list();
        request.setAttribute("departments", departments);
        List<AdminRole> adminroles = factorySession.createCriteria(AdminRole.class)
                .addOrder(Order.asc("sort")).list();
        request.setAttribute("adminroles", adminroles);
        List<AdminGlobalpermission> adminglobalpermissions = factorySession.createCriteria(AdminGlobalpermission.class)
                .list();
        request.setAttribute("adminglobalpermissions", adminglobalpermissions);
        return view();
    }

    // 用户编辑
    @RequestMapping("edit")
    public String edit() {
        int adminId = request.getParameter("adminid") == null ? 0 : Integer.parseInt(request.getParameter("adminid"));
        Admin admin = adminId == 0 ? new Admin() : factorySession.get(Admin.class, adminId);
        if (adminId == 0) {
            AdminGlobalpermission adminGlobalpermission = factorySession.load(AdminGlobalpermission.class, 1);
            admin.setAdminGlobalpermission(adminGlobalpermission);
            admin.setFace("/image/admin/main/defaultface.jpg");
        }
        request.setAttribute("admin", admin);
        if (adminId == 0 || adminId != 1) {
            List<Integer> adminroleIds = new ArrayList<Integer>(); // 用户绑定的角色
            if (adminId > 0)
                for (AdminReAdminRole arar : admin.getAdminReAdminRoles())
                    adminroleIds.add(arar.getAdminRole().getId());
            request.setAttribute("adminroleIds", adminroleIds);
            List<AdminRole> adminroles = factorySession.createCriteria(AdminRole.class)
                    .addOrder(Order.asc("sort")).list();
            request.setAttribute("adminroles", adminroles);
            List<AdminGlobalpermission> adminglobalpermissions = factorySession.createCriteria(AdminGlobalpermission.class)
                    .list();
            request.setAttribute("adminglobalpermissions", adminglobalpermissions);
        }
        List<Department> departments = factorySession.createCriteria(Department.class).addOrder(Order.asc("sort"))
                .list();
        request.setAttribute("departments", departments);
        List<Columns> columnses = new ArrayList<Columns>();
        List<Columns> columnsForZhuanties = new ArrayList<Columns>();
        List<Zhuanti> zhuantis = new ArrayList<Zhuanti>();
        List<Integer> zhuantiIds = new ArrayList<Integer>();
        List<Columns> columns1es = factorySession.createCriteria(Columns.class)
                .add(Restrictions.eq("parentId", 0)).addOrder(Order.asc("sort")).list();
        for (Columns columns1 : columns1es) {
            List<Columns> columns2Temp = factorySession.createCriteria(Columns.class)
                    .add(Restrictions.eq("columnsType.id", 1))
                    .add(Restrictions.eq("parentId", columns1.getId()))
                    .addOrder(Order.asc("sort")).list();
            if (columns1.getColumnsType().getId() == 1 || columns2Temp.size() > 0)
                columnses.add(columns1);
            if (columns2Temp.size() > 0)
                for (Columns columns2 : columns2Temp) columnses.add(columns2);
            if (columns1.getColumnsType().getId() == 6) {
                if (!zhuantiIds.contains(columns1.getZhuanti().getId())) {
                    zhuantis.add(columns1.getZhuanti());
                    zhuantiIds.add(columns1.getZhuanti().getId());
                }
                columnsForZhuanties.add(columns1);
            }
        }
        request.setAttribute("columnses", columnses);
        request.setAttribute("zhuantis", zhuantis);
        request.setAttribute("columnsForZhuanties", columnsForZhuanties);
        request.setAttribute("callbackparams", StringHelper.cnEncode(request.getParameter("callbackparams")));
        return view();
    }

    // 用户编辑处理
    @RequestMapping("editdo")
    @ResponseBody
    public void editdo() {
        checkAdminPermission("yunwei_organ_user");
        int adminId = Integer.parseInt(request.getParameter("adminid"));
        String account = request.getParameter("account");
        if (adminId != 1) {
            if (account.equals("admin")) {
                PageHelper.alertAndGoBack("admin为特殊账号不能使用，请重新输入");
                return;
            }
            int exist = Integer.parseInt(factorySession.createCriteria(Admin.class)
                    .add(Restrictions.eq("account", account))
                    .add(Restrictions.ne("id", adminId))
                    .setProjection(Projections.count("id"))
                    .uniqueResult().toString());
            if (exist > 0) {
                PageHelper.alertAndGoBack("账号已存在，请重新输入");
                return;
            }
        }
        Admin admin = adminId == 0 ? new Admin() : factorySession.load(Admin.class, adminId, LockMode.PESSIMISTIC_WRITE);
        Department department = factorySession.load(Department.class,
                Integer.parseInt(request.getParameter("departmentid")));
        admin.setDepartment(department);
        if (adminId != 1) {
            admin.setAccount(account);
            if (adminId == 0) admin.setPassword(SecurityHelper.md5Encrypt(admin.getAccount() + "_" + "123456"));
            AdminGlobalpermission adminglobalpermission = factorySession.load(AdminGlobalpermission.class,
                    Integer.parseInt(request.getParameter("adminglobalpermissionid")));
            admin.setAdminGlobalpermission(adminglobalpermission);
        }
        admin.setName(request.getParameter("name"));
        admin.setFace(request.getParameter("face"));
        admin.setSex(request.getParameter("sex"));
        admin.setPosition(request.getParameter("position"));
        admin.setMobile(request.getParameter("mobile"));
        admin.setEmail(request.getParameter("email"));
        admin.setWeixinId(request.getParameter("weixinid"));
        admin.setDescription(request.getParameter("description"));
        admin.setSort(Integer.parseInt(request.getParameter("sort")));
        if (adminId == 0) factorySession.save(admin);
        recordLog((adminId == 0 ? "新增" : "修改") + "用户《" + admin.getAccount().trim() + "》");
        if (adminId != 1) {
            // 非超级管理员
            List<Integer> adminroleIds = DataHelper.convertToIntegerList(request.getParameterValues("adminroleids"));
            if (adminId > 0) {
                if (admin.getAdminReAdminRoles().size() > 0) {
                    // 删除原来的角色映射关系
                    List<Object> arars = new ArrayList<>();
                    for (AdminReAdminRole arar : admin.getAdminReAdminRoles()) {
                        if (!adminroleIds.contains(arar.getAdminRole().getId())) arars.add(arar);
                        else adminroleIds.remove(Integer.valueOf(arar.getAdminRole().getId()));
                    }
                    factorySession.delete(arars);
                }
            }
            if (adminroleIds.size() > 0) {
                // 创建新的角色映射关系
                List<AdminRole> adminroles = factorySession.createCriteria(AdminRole.class)
                        .add(Restrictions.in("id", adminroleIds))
                        .list();
                for (AdminRole adminrole : adminroles) {
                    AdminReAdminRole arar = new AdminReAdminRole();
                    arar.setAdmin(admin);
                    arar.setAdminRole(adminrole);
                    factorySession.save(arar);
                }
            }
        }
        PageHelper.alertAndRedirect("保存成功", "./?" +
                StringHelper.cnEncode(request.getParameter("callbackparams")));
    }

    // 密码重置
    @RequestMapping("resetpwd")
    @ResponseBody
    public void resetpwd() {
        checkAdminPermission("yunwei_organ_user");
        int adminId = Integer.parseInt(request.getParameter("adminid"));
        Admin admin = factorySession.load(Admin.class, adminId, LockMode.PESSIMISTIC_WRITE);
        admin.setPassword(SecurityHelper.md5Encrypt(admin.getAccount() + "_" + "123456"));
        recordLog("重置用户《" + admin.getAccount().trim() + "》密码");
        PageHelper.alertAndRedirect("重置密码成功，新密码为：123456", "./?" +
                StringHelper.cnEncode(request.getParameter("callbackparams")));
    }

    // 用户删除
    @RequestMapping("delete")
    @ResponseBody
    public void delete() {
        checkAdminPermission("yunwei_organ_user");
        String[] adminIds = request.getParameter("adminids").split(",");
        List<Admin> admins = factorySession.createCriteria(Admin.class)
                .add(Restrictions.in("id", DataHelper.convertToIntegerArray(adminIds)))
                .setLockMode(LockMode.PESSIMISTIC_WRITE).list();
        for (Admin admin : admins) factorySession.delete(admin);
        recordLog("删除《" + admins.get(0).getAccount().trim() + "...》等" + admins.size() + "位用户");
        PageHelper.alertAndRedirect("删除成功", "./?" + request.getParameter("callbackparams"));
    }

}
